package com.bsoft.gol.hcs.specialist.dao;

import com.bsoft.gol.hcs.specialist.bean.request.PatientMedicalDataRequest;
import com.bsoft.gol.hcs.specialist.bean.response.InspectResponse;
import com.bsoft.gol.hcs.specialist.bean.response.PatientMedicalDataCollectResponse;
import com.bsoft.gol.hcs.specialist.bean.vo.ExamReportVo;
import com.bsoft.gol.hcs.specialist.bean.vo.VrInpatientVisitRecordVo;
import com.bsoft.gol.hcs.specialist.entity.PatientMedicalDataCollectEntity;
import com.bsoft.gol.hcs.specialist.entity.PrescriptionRecordEntity;
import com.bsoft.gol.hcs.utils.CommonUtils;
import com.bsoft.gol.hcs.utils.Constants;
import com.bsoft.gol.hcs.utils.DateUtils;
import com.bsoft.gol.hcs.visitrecord.entity.VrSurgicalRecord;
import com.google.common.collect.Lists;
import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.HibernateSupportDelegateDAO;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.util.converter.ConversionUtils;
import hcn.base.VrOutpatientVisitRecord;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.CriteriaSpecification;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 按照病种配置采集的信息dao
 *
 * @author niule
 */
public abstract class PatientMedicalDataCollectDAO extends HibernateSupportDelegateDAO<PatientMedicalDataCollectEntity> {

    @DAOMethod(sql = "select count(0) from PatientMedicalDataCollectEntity where chronicDiseaseId=:chronicDiseaseId and recordId=:recordId and recordType=:recordType ")
    public abstract Long getCollectDateByDiseaseIdAndRecordIdAndType(@DAOParam("chronicDiseaseId") Long chronicDiseaseId, @DAOParam("recordId") String recordId, @DAOParam("recordType") Integer recordType);

    @DAOMethod(sql = "update PatientMedicalDataCollectEntity set followRecordId=:followRecordId  where id=:id ")
    public abstract void updateCollectDateFollowRecordId(@DAOParam("followRecordId") Long followRecordId, @DAOParam("id") Long id);

    @DAOMethod(sql = "from PatientMedicalDataCollectEntity where followRecordId=:followRecordId ")
    public abstract PatientMedicalDataCollectEntity getRecordIdByFollowUpRecordId(@DAOParam("followRecordId") Long followRecordId);


    /**
     * 查询门诊/住院记录
     *
     * @param request 入参
     * @return 门诊住院信息
     */
    public List<PatientMedicalDataCollectResponse> queryPatientMedicalDataListByCardAndDiseaseId(PatientMedicalDataRequest request) {
        HibernateStatelessResultAction<List<PatientMedicalDataCollectResponse>> action = new AbstractHibernateStatelessResultAction<List<PatientMedicalDataCollectResponse>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT p.id as collectId, r.organization_id as organizationId,r.organization_name as organizationName,r.department_id as departmentId,r.department_name as departmentName");
                if (Constants.ONE_STRING.equals(request.getRecordType())) {
                    sqlBuilder.append(",r.visit_record_id as recordId,r.visit_no as visitId,r.main_diagnosis_code as mainDiagnosisCode,r.main_diagnosis_name as mainDiagnosisName,r.start_time as startTime ");
                } else {
                    sqlBuilder.append(",r.hospital_record_id as recordId,r.in_hospital_record_code as visitId,r.admission_diagnosis as admissionDiagnosis,r.discharge_diagnosis as dischargeDiagnosis,r.admission_time as startTime ");
                }
                sqlBuilder.append(" from patient_medical_data_collect p ");
                if (Constants.ONE_STRING.equals(request.getRecordType())) {
                    sqlBuilder.append("inner join vr_outpatient_visit_record r on r.visit_record_id=p.record_id ");
                } else {
                    sqlBuilder.append("inner join vr_inpatient_visit_record r on r.hospital_record_id=p.record_id ");
                }
                if (StringUtils.isNotEmpty(request.getBusinessId())) {
                    sqlBuilder.append(" where p.chronic_disease_id=:diseaseId and p.record_id=:businessId ");
                } else {
                    sqlBuilder.append(" where p.card_number=:cardNumber and p.card_type=:cardType and p.chronic_disease_id=:diseaseId and p.record_time>=:startTime and p.record_time<=:endTime and p.follow_record_id is null ");
                }

                Query query = ss.createSQLQuery(sqlBuilder.toString());
                if (StringUtils.isNotEmpty(request.getBusinessId())) {
                    query.setParameter("businessId", request.getBusinessId());
                    query.setParameter("diseaseId", request.getDiseaseId());
                } else {
                    query.setParameter("cardNumber", request.getCardNumber());
                    query.setParameter("cardType", request.getCardType());
                    query.setParameter("diseaseId", request.getDiseaseId());
                    query.setParameter("startTime", request.getStartTime());
                    query.setParameter("endTime", request.getEndTime());
                }

                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, String>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    List<PatientMedicalDataCollectResponse> collectEntityList = Lists.newArrayList();
                    for (Map map : list) {
                        PatientMedicalDataCollectResponse collectResponse = ConversionUtils.convert(map, PatientMedicalDataCollectResponse.class);
                        collectEntityList.add(collectResponse);
                    }
                    setResult(collectEntityList);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询住院记录
     *
     * @param businessId 入参
     * @return 住院信息
     */
    public VrInpatientVisitRecordVo queryInpatientRecordBybusinessId(final String businessId) {
        HibernateStatelessResultAction<VrInpatientVisitRecordVo> action = new AbstractHibernateStatelessResultAction<VrInpatientVisitRecordVo>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT r.organization_id as organizationId,r.organization_name as organizationName,r.department_id as departmentId,r.department_name as departmentName");
                sqlBuilder.append(",r.attending_doctor_id as doctorId,r.attending_doctor_name as doctorName,r.hospital_record_id as hospitalRecordId,r.in_hospital_record_code as inHospitalRecordCode");
                sqlBuilder.append(",r.admission_time as admissionTime,r.ward_code as wardCode,r.ward_name as wardName");
                sqlBuilder.append(" from vr_inpatient_visit_record r where r.hospital_record_id=:businessId limit 1 ");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("businessId", businessId);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, String>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    VrInpatientVisitRecordVo inpatientVisitRecord = ConversionUtils.convert(list.get(0), VrInpatientVisitRecordVo.class);
                    setResult(inpatientVisitRecord);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询住院记录
     *
     * @param businessId 入参
     * @return 住院信息
     */
    public List<Map<String, String>> queryVrVisitDiagnosisByBusinessId(final String businessId) {
        HibernateStatelessResultAction<List<Map<String, String>>> action = new AbstractHibernateStatelessResultAction<List<Map<String, String>>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT v.diseases_name as admissionDiagnosis,v.diseases_code as dischargeDiagnosisCode");
                sqlBuilder.append(" from vr_visit_diagnosis v where v.business_id=:businessId and v.diagnosis_service_type='1' ");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("businessId", businessId);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, String>> list = query.list();
                setResult(list);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询门诊记录
     *
     * @param businessId 入参
     * @return 门诊住院信息
     */
    public VrOutpatientVisitRecord queryVisitRecordBybusinessId(final String businessId) {
        HibernateStatelessResultAction<VrOutpatientVisitRecord> action = new AbstractHibernateStatelessResultAction<VrOutpatientVisitRecord>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT r.organization_id as organizationId,r.organization_name as organizationName,r.department_id as departmentId,r.department_name as departmentName,r.start_time as startTime");
                sqlBuilder.append(",r.doctor_id as doctorId,r.doctor_name as doctorName ,r.visit_record_id as visitRecordId,r.visit_no as visitNo,r.main_diagnosis_code as mainDiagnosisCode,r.main_diagnosis_name as mainDiagnosisName");
                sqlBuilder.append(" from vr_outpatient_visit_record r where r.visit_record_id=:businessId ");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("businessId", businessId);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, String>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    VrOutpatientVisitRecord outpatientVisitRecord = ConversionUtils.convert(list.get(0), VrOutpatientVisitRecord.class);
                    setResult(outpatientVisitRecord);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询门诊/住院对应的手术记录
     *
     * @param businessId 入参
     * @return 门诊住院信息
     */
    public List<VrSurgicalRecord> querySurgicalListBybusinessId(final String businessId) {
        HibernateStatelessResultAction<List<VrSurgicalRecord>> action = new AbstractHibernateStatelessResultAction<List<VrSurgicalRecord>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT v.operation_name as operationName,v.operation_code as operationCode,v.operation_incision_description as operationIncisionDescription,v.operation_incision_heal_level as operationIncisionHealLevel" +
                        ",v.anesthesiaWayCode as anesthesiaWayCode,v.anesthesiaWayName as anesthesiaWayName,v.start_time as startTime from vr_surgical_record v where v.business_id=:businessId");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("businessId", businessId);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, String>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    List<VrSurgicalRecord> surgicalRecordList = Lists.newArrayList();
                    for (Map map : list) {
                        VrSurgicalRecord surgicalRecord = ConversionUtils.convert(map, VrSurgicalRecord.class);
                        surgicalRecordList.add(surgicalRecord);
                    }
                    setResult(surgicalRecordList);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询门诊/住院对应的处方记录
     *
     * @param businessId 入参
     * @return 门诊住院信息
     */
    public List<PrescriptionRecordEntity> queryPrescriptionListBybusinessId(final String businessId) {
        HibernateStatelessResultAction<List<PrescriptionRecordEntity>> action = new AbstractHibernateStatelessResultAction<List<PrescriptionRecordEntity>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT p.drug_detail_id as drugDetailId,p.drug_name as drugName,p.drug_specifications as drugSpecifications,p.once_dosage as onceDosage" +
                        ",p.dosage_unit as dosageUnit,p.drug_using_rate as drugUsingRate,p.drug_use_pathways_code as drugUsePathwaysCode,p.drug_use_pathways_name as drugUsePathwaysName" +
                        ",p.drug_using_rate_name as drugUsingRateName,p.medicine_days as medicineDays from prescription_record p where p.business_id=:businessId");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("businessId", businessId);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, String>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    List<PrescriptionRecordEntity> prescriptionRecordEntityList = Lists.newArrayList();
                    for (Map map : list) {
                        PrescriptionRecordEntity prescriptionRecordEntity = ConversionUtils.convert(map, PrescriptionRecordEntity.class);
                        prescriptionRecordEntityList.add(prescriptionRecordEntity);
                    }
                    setResult(prescriptionRecordEntityList);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询门诊/住院对应的检验报告信息
     *
     * @param businessId 入参
     * @return 检查报告信息
     */
    public List<InspectResponse> queryInspectListBybusinessId(final String businessId) {
        HibernateStatelessResultAction<List<InspectResponse>> action = new AbstractHibernateStatelessResultAction<List<InspectResponse>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT r.sample_type_code as sampleTypeCode,r.sample_type_name as sampleTypeName,r.report_time as reportTime,d.test_id as testId,d.test_name as testName" +
                        ",d.test_result as testResult,d.result_code as resultCode,d.result_hint as resultHint,d.result_qualitative as resultQualitative,d.result_unit as resultUnit " +
                        "from inspect_report_record r left join inspect_report_routine_detail d on r.inspect_report_record_id=d.inspect_report_id where r.business_id=:businessId");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("businessId", businessId);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, String>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    List<InspectResponse> inspectList = Lists.newArrayList();
                    for (Map map : list) {
                        inspectList.add(ConversionUtils.convert(map, InspectResponse.class));
                    }
                    setResult(inspectList);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询门诊/住院对应的检查报告
     *
     * @param businessId 入参
     * @return 检查报告
     */
    public List<ExamReportVo> queryExamReportListBybusinessId(final String businessId) {
        HibernateStatelessResultAction<List<ExamReportVo>> action = new AbstractHibernateStatelessResultAction<List<ExamReportVo>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT e.exam_type_code as examTypeCode,e.exam_type_name as examTypeName,e.exam_item_code as examItemCode,e.exam_item_name as examItemName" +
                        ",e.exam_part_code as examPartCode,e.exam_part_name as examPartName,e.exam_descript as examDescript,e.exam_diagnosis as examDiagnosis,e.execute_datetime as executeDatetime " +
                        ",e.study_id as studyId,e.web_pacs_url as webPacsUrl from exam_report e where e.business_id=:businessId");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("businessId", businessId);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, String>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    List<ExamReportVo> examReportList = Lists.newArrayList();
                    for (Map map : list) {
                        examReportList.add(ConversionUtils.convert(map, ExamReportVo.class));
                    }
                    setResult(examReportList);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 根据记录id查询处置项目
     *
     * @param businessId 入参
     * @return 项目
     */
    public List<Map<String, Object>> queryTreatmentListBybusinessId(final String businessId) {
        HibernateStatelessResultAction<List<Map<String, Object>>> action = new AbstractHibernateStatelessResultAction<List<Map<String, Object>>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT t.treatment_item_code as itemId,t.treatment_item_name as itemName,t.request_datetime as applicationTime from treatment_record t where t.business_id=:businessId");

                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("businessId", businessId);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, Object>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    setResult(list);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询随访记录id
     *
     * @param cardType        卡类型
     * @param cardNumber      卡号
     * @param routeDetailType 随访计划类型
     * @param diseaseId       病种id
     * @param time            时间
     * @return 主键id
     */
    public Long queryFollowUpIdByCard(final String cardType, final String cardNumber, final Byte routeDetailType, final Long diseaseId, final Date time) {
        HibernateStatelessResultAction<Long> action = new AbstractHibernateStatelessResultAction<Long>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                String startTime = DateUtils.dateFormate(time, "yyyy-MM-dd");
                String endTime = DateUtils.dateFormate(DateUtils.dateAddMonth(time, Constants.ONE), "yyyy-MM-dd");
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT record_id as recordId from follow_up_records where card_type=:cardType and card_number=:cardNumber and disease_type_id=:diseaseId " +
                        " and route_detail_type=:routeDetailType and follow_up_status in(0,2) and auto_create_flag='0' and plan_time>=:startTime and plan_time<=:endTime order by plan_time asc ");

                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("cardType", cardType);
                query.setParameter("cardNumber", cardNumber);
                query.setParameter("diseaseId", diseaseId);
                query.setParameter("routeDetailType", routeDetailType);
                query.setParameter("startTime", startTime);
                query.setParameter("endTime", endTime);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String, Object>> list = query.list();
                if (CommonUtils.isNotEmpty(list)) {
                    setResult(Long.valueOf(list.get(0).get("recordId").toString()));
                } else {
                    setResult(null);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }
}
